<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
<title>Structure of SympyCore</title>
<meta name="author" content="Pearu Peterson" />
<style type="text/css">

/*
:Author: Pearu Peterson
:Contact: pearu.peterson AT gmail DOT com
:Copyright: This stylesheet has been placed in the public domain.

Stylesheet for use with Docutils.
*/

@import url(html4css1.css);

/* Your customizations go here.  For example: */

body {
    margin:0px;
    padding:25px;
    background-color: #ccc;
    font-size: 13px; font-family: arial, sans-serif;
    line-height:1.5em;
}

div.document {
    max-width: 700px;
    color: #000;
    background-color: #fff;
    padding:25px;
    border:5px solid #ddd;
}

div.sidebar {
  margin-left: 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

pre, tt {
  font-family: consolas, lucida console, courier new, monospace;
  color: #000080 ;
}

pre.literal-block, pre.doctest-block {
  line-height:1.3em;
  border-top:1px solid #ccc;
  border-bottom:1px solid #ccc;
  background-color:#f0f0f0;
  color: #000080 ;
}

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 0.5em;
  background-color: #fffacd;  
}

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

</style>
</head>
<body>
<div class="document" id="structure-of-sympycore">
<h1 class="title">Structure of SympyCore</h1>
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Pearu Peterson</td></tr>
<tr class="field"><th class="docinfo-name">Website:</th><td class="field-body"><a class="reference" href="http://sympycore.googlecode.com">http://sympycore.googlecode.com</a></td>
</tr>
<tr class="field"><th class="docinfo-name">Created:</th><td class="field-body">March 2008</td>
</tr>
</tbody>
</table>
<!-- -*- rest -*- -->
<div class="sidebar">
<p class="first sidebar-title">Table of contents</p>
<div class="contents local last topic">
<ul class="auto-toc simple">
<li><a class="reference" href="#introduction" id="id2" name="id2">1&nbsp;&nbsp;&nbsp;Introduction</a></li>
<li><a class="reference" href="#fundamental-idea" id="id3" name="id3">2&nbsp;&nbsp;&nbsp;Fundamental idea</a><ul class="auto-toc">
<li><a class="reference" href="#implementation-of-principles" id="id4" name="id4">2.1&nbsp;&nbsp;&nbsp;Implementation of principles</a></li>
<li><a class="reference" href="#pre-defined-expression-heads" id="id5" name="id5">2.2&nbsp;&nbsp;&nbsp;Pre-defined expression heads</a></li>
</ul>
</li>
<li><a class="reference" href="#classes-in-sympycore" id="id6" name="id6">3&nbsp;&nbsp;&nbsp;Classes in SympyCore</a><ul class="auto-toc">
<li><a class="reference" href="#low-level-numbers" id="id7" name="id7">3.1&nbsp;&nbsp;&nbsp;Low-level numbers</a></li>
<li><a class="reference" href="#constructing-instances" id="id8" name="id8">3.2&nbsp;&nbsp;&nbsp;Constructing instances</a></li>
<li><a class="reference" href="#various-representations" id="id9" name="id9">3.3&nbsp;&nbsp;&nbsp;Various representations</a></li>
<li><a class="reference" href="#id1" id="id10" name="id10">3.4&nbsp;&nbsp;&nbsp;Constructing instances</a></li>
<li><a class="reference" href="#verbatim-algebra" id="id11" name="id11">3.5&nbsp;&nbsp;&nbsp;Verbatim algebra</a></li>
<li><a class="reference" href="#logic-algebra" id="id12" name="id12">3.6&nbsp;&nbsp;&nbsp;Logic algebra</a></li>
<li><a class="reference" href="#collecting-field" id="id13" name="id13">3.7&nbsp;&nbsp;&nbsp;Collecting field</a></li>
</ul>
</li>
<li><a class="reference" href="#defining-functions-in-sympycore" id="id14" name="id14">4&nbsp;&nbsp;&nbsp;Defining functions in SympyCore</a></li>
<li><a class="reference" href="#how-does-it-work-in-sympycore" id="id15" name="id15">5&nbsp;&nbsp;&nbsp;How does it work in SympyCore?</a><ul class="auto-toc">
<li><a class="reference" href="#how-strings-are-parsed-to-expressions" id="id16" name="id16">5.1&nbsp;&nbsp;&nbsp;How strings are parsed to expressions?</a></li>
<li><a class="reference" href="#how-arbitrary-python-objects-are-converted-to-expressions" id="id17" name="id17">5.2&nbsp;&nbsp;&nbsp;How arbitrary Python objects are converted to expressions?</a></li>
<li><a class="reference" href="#how-algebra-expressions-are-converted-to-other-algebras" id="id18" name="id18">5.3&nbsp;&nbsp;&nbsp;How algebra expressions are converted to other algebras?</a></li>
<li><a class="reference" href="#how-verbatim-expressions-are-converted-to-other-algebras" id="id19" name="id19">5.4&nbsp;&nbsp;&nbsp;How verbatim expressions are converted to other algebras?</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id2" id="introduction" name="introduction">1&nbsp;&nbsp;&nbsp;Introduction</a></h1>
<p>This document gives an overview of data types that are used in
<tt class="docutils literal"><span class="pre">sympycore</span></tt> to represent symbolic expressions. First, the fundametal
idea of defining a Python type <tt class="docutils literal"><span class="pre">Expr</span></tt>, that holds a pair of Python
objects, is explained. Then <tt class="docutils literal"><span class="pre">Expr</span></tt> is used to implement classes that
represent different mathematical concepts --- the actual class
structure of <tt class="docutils literal"><span class="pre">sympycore</span></tt> is outlined. Subsequent sections document
the features of <tt class="docutils literal"><span class="pre">sympycore</span></tt> classes in detail.</p>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id3" id="fundamental-idea" name="fundamental-idea">2&nbsp;&nbsp;&nbsp;Fundamental idea</a></h1>
<p>The fundamental idea behind the implementation of <tt class="docutils literal"><span class="pre">sympycore</span></tt>
classes is based on the following assertions:</p>
<ul class="simple">
<li>Any symbolic expression can be expressed as a pair of <em>expression
head</em> and <em>expression data</em>. The <em>expression head</em> defines
how the <em>expression data</em> is interpreted.</li>
<li>Symbolic expression represents an unevaluated element of an
<em>algebraic structure</em> under consideration. In the following we call
a algebraic structure as an algebra for brevity.  An algebra is
represented by a Python class (an <em>algebra class</em>) and the
instances of this class represent symbolic expressions.</li>
<li>An algebra may define <em>operations</em> between its elements
to form <em>composite</em> symbolic expressions. Each operation is
represented by the corresponding expression head. Since the same
operation may be defined for different algebras then the
same expression head (defining evaluation rules and other methods)
is used for symbolic expressions of different algebra classes.</li>
<li>Symbolic expressions can be constructed directly from expression
head and data parts, or indirectly from performing operations with
other symbolic operations. Direct construction, <tt class="docutils literal"><span class="pre">&lt;Algebra</span>
<span class="pre">class&gt;(&lt;head&gt;,</span> <span class="pre">&lt;data&gt;)</span></tt>, results an unevaluated symbolic expression
instance while indirect construction, <tt class="docutils literal"><span class="pre">&lt;expr1&gt;</span> <span class="pre">&lt;operation&gt;</span>
<span class="pre">&lt;expr2&gt;</span></tt>, evaluates the symbolic expression instance to a canonical
form. Direct construction does not have any argument validity checks for
efficiency and should be used internally by evaluation methods.</li>
</ul>
<div class="section">
<h2><a class="toc-backref" href="#id4" id="implementation-of-principles" name="implementation-of-principles">2.1&nbsp;&nbsp;&nbsp;Implementation of principles</a></h2>
<p>The assertions of the fundamental idea is implemented as follows:</p>
<ul class="simple">
<li>To hold the head and data parts of symbolic expressions, a class
<tt class="docutils literal"><span class="pre">Expr</span></tt> is defined that instances will have an attribute <tt class="docutils literal"><span class="pre">pair</span></tt>
holding the head and data pair.  In a way, the <tt class="docutils literal"><span class="pre">Expr</span></tt> class
represents an algebra with no mathematical properties - it just
holds some <em>head</em> and some <em>data</em>.</li>
<li>To define the algebra operations for symbolic expressions,
subclasses of <tt class="docutils literal"><span class="pre">Expr</span></tt> implement the corresponding methods.</li>
<li>The head parts of symbolic expressions are instances of
<tt class="docutils literal"><span class="pre">sympycore.heads.Head</span></tt> classes that implement the evaluation rules
of the corresponding algebra operations. Since head instances are
singletons then Python <tt class="docutils literal"><span class="pre">is</span></tt> operation can be used for comparing
expression heads.</li>
</ul>
<p>The following section gives an overview of pre-defined expression heads.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id5" id="pre-defined-expression-heads" name="pre-defined-expression-heads">2.2&nbsp;&nbsp;&nbsp;Pre-defined expression heads</a></h2>
<p>All head instances are available as attributes to the holder object
<tt class="docutils literal"><span class="pre">sympycore.core.heads</span></tt>.</p>
<div class="section">
<h3><a id="atomic-heads" name="atomic-heads">2.2.1&nbsp;&nbsp;&nbsp;Atomic heads</a></h3>
<p>SYMBOL</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">SYMBOL</span></tt> head represents any element of
the algebra. The corresponding expression data part can be any
Python object (usually it is a string). <tt class="docutils literal"><span class="pre">SYMBOL</span></tt> head defines no
interpretation rules for the data.</blockquote>
<p>NUMBER</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">NUMBER</span></tt> head represents a generalized
repetition operation of algebra elements. The data part can be any
Python object that supports Python numbers protocol, that is, the
objects type must define all basic arithmetic operations. Usually
the data part contains number instances such as integers, floats,
complex numbers or numbers defined by the
<tt class="docutils literal"><span class="pre">sympycore.arithmetic.numbers</span></tt> module: rational numbers and
arbitrary precision floating point numbers. The data part can also
contain symbolic expression of some other algebra (<em>coefficient
algebra</em>), then such expressions are considered as coefficients that
always commute with the elements of the given algebra.</blockquote>
</div>
<div class="section">
<h3><a id="arithmetic-heads" name="arithmetic-heads">2.2.2&nbsp;&nbsp;&nbsp;Arithmetic heads</a></h3>
<p>POS</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">POS</span></tt> head represents unevaluated unary
positive sign operation. The data part must be a symbolic expression.
For example, <tt class="docutils literal"><span class="pre">Algebra(POS,</span> <span class="pre">a)</span></tt> represents <tt class="docutils literal"><span class="pre">+a</span></tt>.</blockquote>
<p>NEG</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">NEG</span></tt> head represents unevaluated unary
negative sign operation. The data part must be a symbolic
expression.
For example, <tt class="docutils literal"><span class="pre">Algebra(NEG,</span> <span class="pre">a)</span></tt> represents <tt class="docutils literal"><span class="pre">-a</span></tt>.</blockquote>
<p>ADD</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">ADD</span></tt> head represents unevaluated n-ary
addition operation. The data part must be a Python list of symbolic
expression. For example, <tt class="docutils literal"><span class="pre">Algebra(ADD,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt> represents <tt class="docutils literal"><span class="pre">a</span>
<span class="pre">+</span> <span class="pre">b</span> <span class="pre">+</span> <span class="pre">c</span></tt>.</blockquote>
<p>SUB</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">SUB</span></tt> head represents unevaluated n-ary
subtraction operation. The data part must be a Python list of symbolic
expression. For example, <tt class="docutils literal"><span class="pre">Algebra(SUB,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt> represents <tt class="docutils literal"><span class="pre">a</span>
<span class="pre">-</span> <span class="pre">b</span> <span class="pre">-</span> <span class="pre">c</span></tt>.</blockquote>
<p>MUL</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">MUL</span></tt> head represents unevaluated n-ary
multiplication operation. The data part must be a Python list of symbolic
expression. For example, <tt class="docutils literal"><span class="pre">Algebra(MUL,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt> represents <tt class="docutils literal"><span class="pre">a</span>
<span class="pre">*</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">c</span></tt>.</blockquote>
<p>NCMUL</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">NCMUL</span></tt> head represents unevaluated n-ary
non-commutative multiplication operation. The data part must be a
Python list of symbolic expression that are not numbers. For
example, <tt class="docutils literal"><span class="pre">Algebra(NCMUL,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt> represents <tt class="docutils literal"><span class="pre">a</span> <span class="pre">*</span> <span class="pre">b</span> <span class="pre">*</span> <span class="pre">c</span></tt>.</blockquote>
<p>DIV</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">DIV</span></tt> head represents unevaluated n-ary
division operation. The data part must be a Python list of symbolic
expression. For example, <tt class="docutils literal"><span class="pre">Algebra(DIV,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt> represents <tt class="docutils literal"><span class="pre">a</span>
<span class="pre">/</span> <span class="pre">b</span> <span class="pre">/</span> <span class="pre">c</span></tt>.</blockquote>
<p>POW</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">POW</span></tt> head represents unevaluated
exponentiation operation. The data part must be a Python 2-tuple of
symbolic expressions representing base and exponent parts. For
example, <tt class="docutils literal"><span class="pre">Algebra(POW,</span> <span class="pre">(a,</span> <span class="pre">b))</span></tt> represents <tt class="docutils literal"><span class="pre">a</span> <span class="pre">**</span> <span class="pre">b</span></tt>.</blockquote>
<p>TERM_COEFF_DICT</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">TERM_COEFF_DICT</span></tt> head represents
unevaluated unordered addition operation. The data part must be a
Python dictionary of symbolic expression and coefficient pairs.
Coefficients must support number operations.
For example, <tt class="docutils literal"><span class="pre">Algebra(TERM_COEFF_DICT,</span> <span class="pre">{a:2,</span> <span class="pre">b:1})</span></tt> represents
<tt class="docutils literal"><span class="pre">2*a</span> <span class="pre">+</span> <span class="pre">b</span></tt>.</blockquote>
<p>BASE_EXP_DICT</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">BASE_EXP_DICT</span></tt> head represents
unevaluated unordered multiplication operation. The data part must be a
Python dictionary of symbolic expression and exponent pairs.
Exponent objects must support number operations.
For example, <tt class="docutils literal"><span class="pre">Algebra(BASE_EXP_DICT,</span> <span class="pre">{a:2,</span> <span class="pre">b:1})</span></tt> represents
<tt class="docutils literal"><span class="pre">a**2</span> <span class="pre">*</span> <span class="pre">b</span></tt>.</blockquote>
<p>EXP_COEFF_DICT</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">EXP_COEFF_DICT</span></tt> head represents
unevaluated unordered polynomial addition operation. The data part
must be a <tt class="docutils literal"><span class="pre">Pair</span></tt> instance containing a tuple of variable
expressions and a dictionary of integer exponents and coefficient
pairs.  Coefficient objects must support number operations. For
example, <tt class="docutils literal"><span class="pre">Algbera(EXP_COEFF_DICT,</span> <span class="pre">Pair((x,</span> <span class="pre">sin(x)),</span> <span class="pre">{(0,1):2,</span>
<span class="pre">(2,3):5}))</span></tt> represents <tt class="docutils literal"><span class="pre">2*sin(x)</span> <span class="pre">+</span> <span class="pre">5*x**2*sin(x)**3</span></tt>.</blockquote>
<p>LSHIFT, RSHIFT</p>
<blockquote>
Symbolic expressions with <tt class="docutils literal"><span class="pre">LSHIFT</span></tt> and <tt class="docutils literal"><span class="pre">RSHIFT</span></tt> heads represent
unevaluated n-ary <em>left-shift</em> and <em>right-shift</em> operations. The
data part must be a list of symbolic expressions.
For example, <tt class="docutils literal"><span class="pre">Algebra(LSHIFT,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt> represents <tt class="docutils literal"><span class="pre">a&lt;&lt;b&lt;&lt;c</span></tt>.</blockquote>
<p>INVERT, BOR, BXOR, BAND, FLOORDIV</p>
<blockquote>
Binary operations.</blockquote>
</div>
<div class="section">
<h3><a id="logic-heads" name="logic-heads">2.2.3&nbsp;&nbsp;&nbsp;Logic heads</a></h3>
<p>NOT</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">NOT</span></tt> head represents unevaluated unary
logical <em>negation</em> operation. The data part must be a symbolic
expression that is an instance of a <tt class="docutils literal"><span class="pre">Logic</span></tt> algebra class. For
example, <tt class="docutils literal"><span class="pre">Logic(NOT,</span> <span class="pre">a)</span></tt> represents <tt class="docutils literal"><span class="pre">not</span> <span class="pre">a</span></tt>.</blockquote>
<p>OR</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">OR</span></tt> head represents unevaluated n-ary
logical <em>disjunction</em> operation. The data part must be a list of
<tt class="docutils literal"><span class="pre">Logic</span></tt> instances. For example, <tt class="docutils literal"><span class="pre">Logic(OR,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt>
represents <tt class="docutils literal"><span class="pre">a</span> <span class="pre">or</span> <span class="pre">b</span> <span class="pre">or</span> <span class="pre">c</span></tt>.</blockquote>
<p>XOR</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">XOR</span></tt> head represents unevaluated n-ary
logical <em>exclusive disjunction</em> operation. The data part must be a
list of <tt class="docutils literal"><span class="pre">Logic</span></tt> instances. For example, <tt class="docutils literal"><span class="pre">Logic(XOR,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt>
represents <tt class="docutils literal"><span class="pre">a</span> <span class="pre">xor</span> <span class="pre">b</span> <span class="pre">xor</span> <span class="pre">c</span></tt>.</blockquote>
<p>AND</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">AND</span></tt> head represents unevaluated n-ary
logical <em>conjunction</em> operation. The data part must be a list of
<tt class="docutils literal"><span class="pre">Logic</span></tt> instances. For example, <tt class="docutils literal"><span class="pre">Logic(AND,</span> <span class="pre">[a,</span> <span class="pre">b,</span> <span class="pre">c])</span></tt>
represents <tt class="docutils literal"><span class="pre">a</span> <span class="pre">and</span> <span class="pre">b</span> <span class="pre">and</span> <span class="pre">c</span></tt>.</blockquote>
<p>IMPLIES</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">IMPLIES</span></tt> head represents unevaluated
binary logical <em>conditional</em> operation (if-then). The data part must
be a 2-tuple of <tt class="docutils literal"><span class="pre">Logic</span></tt> instances. For example, <tt class="docutils literal"><span class="pre">Logic(IMPLIES,</span>
<span class="pre">(a,</span> <span class="pre">b))</span></tt> represents <tt class="docutils literal"><span class="pre">a</span> <span class="pre">implies</span> <span class="pre">b</span></tt>.</blockquote>
<p>EQUIV</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">EQUIV</span></tt> head represents unevaluated
binary logical <em>biconditional</em> operation (if-and-only-if). The data part must
be a 2-tuple of <tt class="docutils literal"><span class="pre">Logic</span></tt> instances. For example, <tt class="docutils literal"><span class="pre">Logic(EQUIV,</span>
<span class="pre">(a,</span> <span class="pre">b))</span></tt> represents <tt class="docutils literal"><span class="pre">a</span> <span class="pre">equiv</span> <span class="pre">b</span></tt>.</blockquote>
</div>
<div class="section">
<h3><a id="relational-heads" name="relational-heads">2.2.4&nbsp;&nbsp;&nbsp;Relational heads</a></h3>
<p>The symbolic expressions of relational operations are instances of the
<tt class="docutils literal"><span class="pre">Logic</span></tt> algebra class. The data parts of relational operations are Python
2-tuples of symbolic expressions.</p>
<p>EQ, NE, LT, LE, GT, GE</p>
<blockquote>
Symbolic expressions with <tt class="docutils literal"><span class="pre">EQ</span></tt>, <tt class="docutils literal"><span class="pre">NE</span></tt>, <tt class="docutils literal"><span class="pre">LT</span></tt>, <tt class="docutils literal"><span class="pre">LE</span></tt>, <tt class="docutils literal"><span class="pre">GT</span></tt>, or
<tt class="docutils literal"><span class="pre">GE</span></tt> heads represent unevaluated binary relational operations
<em>equal</em>, <em>not-equal</em>, <em>less-than</em>, <em>less-equal</em>, <em>greater-than</em>, or
<em>greater-equal</em>, respectively.  For example, <tt class="docutils literal"><span class="pre">Logic(LT,</span> <span class="pre">(a,</span> <span class="pre">b))</span></tt>
represents <tt class="docutils literal"><span class="pre">a</span> <span class="pre">&lt;</span> <span class="pre">b</span></tt>.</blockquote>
<p>IN, NOTIN</p>
<blockquote>
Symbolic expressions with <tt class="docutils literal"><span class="pre">IN</span></tt> or <tt class="docutils literal"><span class="pre">NOTIN</span></tt> heads represent
unevaluated binary relational operations <em>in</em> or <em>not-in</em>,
respectively. The left-hand-side operand should be an element of the
right-hand-side operand which is a <tt class="docutils literal"><span class="pre">Set</span></tt> instance.</blockquote>
<p>IS, ISNOT</p>
<blockquote>
Symbolic expressions with <tt class="docutils literal"><span class="pre">IN</span></tt> or <tt class="docutils literal"><span class="pre">NOTIN</span></tt> heads represent
unevaluated binary relational operations <em>in</em> or <em>not-in</em>,
respectively.</blockquote>
</div>
<div class="section">
<h3><a id="container-heads" name="container-heads">2.2.5&nbsp;&nbsp;&nbsp;Container heads</a></h3>
<p>TUPLE, LIST, DICT</p>
<blockquote>
Symbolic expressions with <tt class="docutils literal"><span class="pre">TUPLE</span></tt>, <tt class="docutils literal"><span class="pre">LIST</span></tt>, or <tt class="docutils literal"><span class="pre">DICT</span></tt> heads
represent unevaluated tuple, list, or dict expressions,
respectively. The data parts must be Python tuple, list, or dict
instances, respectively, of symbolic expressions. For example,
<tt class="docutils literal"><span class="pre">Algebra(TUPLE,</span> <span class="pre">(a,</span> <span class="pre">b,</span> <span class="pre">c))</span></tt> represents <tt class="docutils literal"><span class="pre">(a,b,c)</span></tt>.</blockquote>
</div>
<div class="section">
<h3><a id="special-heads" name="special-heads">2.2.6&nbsp;&nbsp;&nbsp;Special heads</a></h3>
<p>CALLABLE</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">CALLABLE</span></tt> head represents an element
of functions algebra. The data part must be Python callable object
that returns a symbolic expression representing an element of
functions values algebra. Symbolic expressions with <tt class="docutils literal"><span class="pre">CALLABLE</span></tt>
head are usually used in connection with <tt class="docutils literal"><span class="pre">APPLY</span></tt> head to represent
unevaluated applied function expressions. In fact, if the callable
data part cannot evaluate its arguments then it should return
<tt class="docutils literal"><span class="pre">Algebra(APPLY,</span> <span class="pre">(FunctionAlgebra(CALLABLE,</span> <span class="pre">&lt;callable&gt;),</span> <span class="pre">&lt;argument1&gt;,</span> <span class="pre">...))</span></tt>.</blockquote>
<p>SPECIAL</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">SPECIAL</span></tt> head does not represent any
element of the given algebra. That said, the data part can hold any
Python object. In practice, data can be Python <tt class="docutils literal"><span class="pre">Ellipsis</span></tt> or
<tt class="docutils literal"><span class="pre">None</span></tt> objects. Also, data can hold extended number instances
(e.g. infinities) of the given algebra.</blockquote>
<p>APPLY</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">APPLY</span></tt> head represents an unevaluated
applied function expression. The data part must be a tuple of
symbolic expressions where the first element belongs to functions
algebra and the rest of the elements are function arguments.
For example, <tt class="docutils literal"><span class="pre">Algebra(APPLY,</span> <span class="pre">(f,</span> <span class="pre">x,</span> <span class="pre">y))</span></tt> represents <tt class="docutils literal"><span class="pre">f(x,</span> <span class="pre">y)</span></tt>.</blockquote>
<p>KWARG</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">KWARG</span></tt> head represents a keyword
argument to symbolic functions. The data part must be a 2-tuple of
symbolic expressions. For example, <tt class="docutils literal"><span class="pre">Algebra(KWARG,</span> <span class="pre">(a,b))</span></tt>
represents <tt class="docutils literal"><span class="pre">a=b</span></tt>.</blockquote>
<p>SUBSCRIPT</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">SUBSCRIPT</span></tt> head represents an
unevaluated applied subscript expression. The data part must be a
tuple of symbolic expressions. For example, <tt class="docutils literal"><span class="pre">Algebra(SUBSCRIPT,</span>
<span class="pre">(f,i,j))</span></tt> represents <tt class="docutils literal"><span class="pre">f[i,j]</span></tt>.</blockquote>
<p>SLICE</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">SLICE</span></tt> head represents an
unevaluated slice expression. The data part must be a
3-tuple of symbolic expressions. For example, <tt class="docutils literal"><span class="pre">Algebra(SLICE,</span>
<span class="pre">(i:Algebra(SPECIAL,</span> <span class="pre">None):k))</span></tt> represents <tt class="docutils literal"><span class="pre">i::k</span></tt>.</blockquote>
<p>ATTR</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">SUBSCRIPT</span></tt> head represents an
unevaluated applied attribute expression. The data part must be a
2-tuple of symbolic expressions. For example, <tt class="docutils literal"><span class="pre">Algebra(ATTR,</span> <span class="pre">(f,</span>
<span class="pre">a))</span></tt> represents <tt class="docutils literal"><span class="pre">f.a</span></tt>.</blockquote>
<p>LAMBDA</p>
<blockquote>
A symbolic expression with <tt class="docutils literal"><span class="pre">SUBSCRIPT</span></tt> head represents a
lambda expression. The data part must be a 2-tuple of a tuple
(lambda arguments) and symbolic expression (lambda body). For
example, <tt class="docutils literal"><span class="pre">Algebra(LAMBDA,</span> <span class="pre">((a,b),</span> <span class="pre">c))</span></tt> represents <tt class="docutils literal"><span class="pre">lambda</span> <span class="pre">a,</span> <span class="pre">b:</span>
<span class="pre">c</span></tt>.</blockquote>
</div>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id6" id="classes-in-sympycore" name="classes-in-sympycore">3&nbsp;&nbsp;&nbsp;Classes in SympyCore</a></h1>
<p>The following diagram summarizes what classes <tt class="docutils literal"><span class="pre">sympycore</span></tt> is going
to define:</p>
<pre class="literal-block">
object
  Expr
    Pair
    Algebra
      Verbatim
      Logic
      Ring
        CommutativeRing
          Calculus
          Unit
        Matrix

  Infinity

  tuple
    mpq
  mpqc
  mpf, mpc
  int, long, float, complex
</pre>
<div class="section">
<h2><a class="toc-backref" href="#id7" id="low-level-numbers" name="low-level-numbers">3.1&nbsp;&nbsp;&nbsp;Low-level numbers</a></h2>
<p>Many algebras define numbers as generalized repetitions of the algebra
unit element. Sympycore uses and defines the following number types
for purely numerical tasks, i.e. both operands and operation results
are numbers):</p>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="83%" />
</colgroup>
<tbody valign="top">
<tr><td>int, long</td>
<td>integers of arbitrary size</td>
</tr>
<tr><td>mpq</td>
<td>fractions</td>
</tr>
<tr><td>mpf</td>
<td>arbitrary precision floating point numbers</td>
</tr>
<tr><td>mpqc</td>
<td>complex numbers with rational parts</td>
</tr>
<tr><td>mpc</td>
<td>arbitrary precision complex floating point numbers</td>
</tr>
</tbody>
</table>
<p>Python <tt class="docutils literal"><span class="pre">float</span></tt> and <tt class="docutils literal"><span class="pre">complex</span></tt> instances are converted to <tt class="docutils literal"><span class="pre">mpf</span></tt>
and <tt class="docutils literal"><span class="pre">mpc</span></tt> instances, respectively, when used in operations with
symbolic expressions.</p>
<p>These number types are called &quot;low-level&quot; numbers because some of
their properties may be unusual for generic numbers (e.g. mpf is
derived from Python tuple) but these properties are introduced to
improve the efficiency of number operations.</p>
<p>For example, <tt class="docutils literal"><span class="pre">mpq</span></tt> number is assumed to hold a normalized rational
number that is not integer.  Operations between <tt class="docutils literal"><span class="pre">mpq</span></tt> instances that
would produce integer result, will return <tt class="docutils literal"><span class="pre">int</span></tt> (or <tt class="docutils literal"><span class="pre">long</span></tt>)
instance. Similarly, the real valued result of an operation between
complex numbers <tt class="docutils literal"><span class="pre">mpqc</span></tt> (or <tt class="docutils literal"><span class="pre">mpc</span></tt>) will be an instance of <tt class="docutils literal"><span class="pre">int</span></tt>
or <tt class="docutils literal"><span class="pre">long</span></tt> or <tt class="docutils literal"><span class="pre">mpq</span></tt> (or <tt class="docutils literal"><span class="pre">mpf</span></tt>) type.</p>
<div class="warning">
<p class="first admonition-title">Warning</p>
<p class="last">THE CONTENT BELOW NEEDS A REVISION.</p>
</div>
<div class="warning">
<p class="first admonition-title">Warning</p>
<p class="last">The Python code fragments shown in this section are presented only
for illustration purposes. The <tt class="docutils literal"><span class="pre">sympycore</span></tt> may use slightly
different implementation (explained in the following sections) that
gives a better performance. However, the basic idea remain the same.</p>
</div>
<p>In <tt class="docutils literal"><span class="pre">sympycore</span></tt>, any symbolic expression is defined as an instance of a
<tt class="docutils literal"><span class="pre">Expr</span></tt> class (or one of its subclasses):</p>
<pre class="literal-block">
class Expr(object):

    def __init__(self, head, data):
        self.pair = (head, data)

    head = property(lambda self: self.pair[0])
    data = property(lambda self: self.pair[1])
</pre>
<p>To define an algebra with additional properties that define opertions
between its elements, a Python class is derived from the <tt class="docutils literal"><span class="pre">Expr</span></tt>
class:</p>
<pre class="literal-block">
class Algebra(Expr):

     def operation(self, other):
         ...
         return result
</pre>
<p>where an operation between algerba elements is implemented in a method
<tt class="docutils literal"><span class="pre">operation</span></tt>.</p>
<p>For example. a commutative ring element can be represented as an
instance of the following class:</p>
<pre class="literal-block">
class CommutativeRing(Expr):

     def __add__(self, other):
         return CommutativeRing('+', (self, other))

     __radd__ = __add__ # addition is commutative

     def __mul__(self, other):
         return CommutativeRing('*', (self, other))
</pre>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id8" id="constructing-instances" name="constructing-instances">3.2&nbsp;&nbsp;&nbsp;Constructing instances</a></h2>
<p>For convenience, one can provide additional methods or functions that
will simplify creating instances of the <tt class="docutils literal"><span class="pre">Expr</span></tt> based classes. For
example, to construct a symbol of a commutative ring, one can define
the following function:</p>
<pre class="literal-block">
def Symbol(name):
    return CommutativeRing('S', name)
</pre>
<p>To construct a number of a commutative ring, one can define:</p>
<pre class="literal-block">
def Number(value):
    return CommutativeRing('N', value)
</pre>
<p>To construct an applied unary function with a value in a commutative
ring, one can define:</p>
<pre class="literal-block">
def F(x):
    &quot;Return the value of function F&quot;
    return &lt;result&gt;

def Apply(function, argument):
    return CommutativeRing(function, argument)
</pre>
<p>Since <tt class="docutils literal"><span class="pre">sympycore</span></tt> defines many classes representing different
algebras, the functions above are usually implemented as Python
<tt class="docutils literal"><span class="pre">classmethod</span></tt>-s of the corresponding algebra classes. Also, the
<tt class="docutils literal"><span class="pre">head</span></tt> parts may be changed to anything more appropiate.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id9" id="various-representations" name="various-representations">3.3&nbsp;&nbsp;&nbsp;Various representations</a></h2>
<p>Note that a fixed symbolic expression may have different but
mathematically equivalent representations. For example, consider the
following symbolic expression:</p>
<pre class="literal-block">
x**3 + 2*y
</pre>
<p>This expression may have at least three different representations:</p>
<pre class="literal-block">
Ring(head='ADD',   data=(x**3, 2*y))
Ring(head='TERMS', data=((x**3, 1), (y, 2)))
Ring(head=(x,y),   data=(((3,0), 1), ((0,1), 2)))
</pre>
<p>where the <tt class="docutils literal"><span class="pre">data</span></tt> structures are interpreted as follows:</p>
<pre class="literal-block">
(x**3) + (2*y)
(x**3) * 1 + y * 2
x**3 * y**0 * 1 + x**0 * y**1 * 2
</pre>
<p>respectively.</p>
<p>In general, there is no preferred representation for a symbolic
expression, each representation has its pros and cons depending on
applications.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id10" id="id1" name="id1">3.4&nbsp;&nbsp;&nbsp;Constructing instances</a></h2>
<p>There are two types of symbolic expressions: atomic and composites.
Atomic expressions are symbols and numbers. Symbols can be considered
as unspecified numbers. Composite expressions are unevaluated forms of
operators or operations defined between symbolic expressions.</p>
<p>In SympyCore, each algebra class defines classmethods
<tt class="docutils literal"><span class="pre">Symbol(&lt;obj&gt;)</span></tt> and <tt class="docutils literal"><span class="pre">Number(&lt;obj&gt;)</span></tt> that can be used to construct
atomic expressions. In fact, they will usually return <tt class="docutils literal"><span class="pre">&lt;Algebra</span>
<span class="pre">class&gt;(SYMBOL,</span> <span class="pre">&lt;obj&gt;)</span></tt> and <tt class="docutils literal"><span class="pre">&lt;Algebra</span> <span class="pre">class&gt;(NUMBER,</span> <span class="pre">&lt;obj&gt;)</span></tt>,
respectively. Regarding nubers, it is callers responsibility to ensure
that <tt class="docutils literal"><span class="pre">&lt;obj&gt;</span></tt> is usable as a number.  Some algebra classes also
define class attributes <tt class="docutils literal"><span class="pre">zero</span></tt> and <tt class="docutils literal"><span class="pre">one</span></tt> holding identity numbers
with respect to addition and multiplication operations. In <tt class="docutils literal"><span class="pre">Logic</span></tt>
algebra, these numbers are aliases to <tt class="docutils literal"><span class="pre">false</span></tt> and <tt class="docutils literal"><span class="pre">true</span></tt> values,
respecitvely.</p>
<p>Depending on the callers need, there are at least three possibilities
in SympyCore to construct composite expressions:</p>
<ol class="arabic simple">
<li>Use <tt class="docutils literal"><span class="pre">&lt;Algebra</span> <span class="pre">class&gt;(&lt;head&gt;,</span> <span class="pre">&lt;data&gt;)</span></tt> that will return an algebra
class instance with given head and data. No evaluation or
canonization is performed. This construction is usually used by
low-level methods that must ensure that the data part contains
proper data, that is, data in a form that the rest of sympycore
can assume.</li>
<li>Use <tt class="docutils literal"><span class="pre">&lt;Algebra</span> <span class="pre">class&gt;.&lt;Operation&gt;(&lt;operands&gt;)</span></tt> class method call
that will perform basic canonization of the operation applied to
operands and returns canonized result as an instance of the algebra
class. This construction is usually used by high-level methods that
must ensure that operands are instances of operands algebra.</li>
<li>Use <tt class="docutils literal"><span class="pre">&lt;Operation&gt;(&lt;operands&gt;)</span></tt> function call that will convert
operands to operands algebra instances and then returns the result
of <tt class="docutils literal"><span class="pre">&lt;Algebra</span> <span class="pre">class&gt;.&lt;Operation&gt;</span></tt> classmethod. This construction
should be used by end-users.</li>
</ol>
<p>There exist also some convenience and implementation specific
possibilities to construct expressions:</p>
<ol class="arabic simple" start="4">
<li>Use <tt class="docutils literal"><span class="pre">&lt;Algebra</span> <span class="pre">class&gt;.convert(&lt;obj&gt;,</span> <span class="pre">typeerror=True)</span></tt> to convert
Python object <tt class="docutils literal"><span class="pre">&lt;obj&gt;</span></tt> to algebra instance. If conversation is not
defined then <tt class="docutils literal"><span class="pre">TypeError</span></tt> is raised by default. When
<tt class="docutils literal"><span class="pre">typeerror=False</span></tt> then <tt class="docutils literal"><span class="pre">NotImplemented</span></tt> is returned instead of
raising the exception.</li>
<li>Use <tt class="docutils literal"><span class="pre">&lt;Algebra</span> <span class="pre">class&gt;(&lt;obj&gt;)</span></tt> that is an alias to <tt class="docutils literal"><span class="pre">&lt;Algebra</span>
<span class="pre">class&gt;.convert(&lt;obj&gt;)</span></tt> call.</li>
</ol>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id11" id="verbatim-algebra" name="verbatim-algebra">3.5&nbsp;&nbsp;&nbsp;Verbatim algebra</a></h2>
<p>SympyCore defines <tt class="docutils literal"><span class="pre">Verbatim</span></tt> class that represents verbatim algebra.
Verbatim algebra contains expressions in unevaluated form. The
verbatim algebra can be used to implement generic methods for
transforming symbolic expressions to strings, or to instances of other
algebras.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id12" id="logic-algebra" name="logic-algebra">3.6&nbsp;&nbsp;&nbsp;Logic algebra</a></h2>
<p>SympyCore defines <tt class="docutils literal"><span class="pre">Logic</span></tt> class that represents n-ary predicate
expressions. The following operations are defined by the <tt class="docutils literal"><span class="pre">Logic</span></tt>
class:</p>
<ol class="arabic simple">
<li><tt class="docutils literal"><span class="pre">Not(x)</span></tt> represents boolean expression <tt class="docutils literal"><span class="pre">not</span> <span class="pre">x</span></tt>. Operand algebra
class is <tt class="docutils literal"><span class="pre">Logic</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">And(x,y,..)</span></tt> represents boolean expression <tt class="docutils literal"><span class="pre">x</span> <span class="pre">and</span> <span class="pre">y</span> <span class="pre">and</span> <span class="pre">..</span></tt>.
Operand algebra class is <tt class="docutils literal"><span class="pre">Logic</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">Or(x,y,..)</span></tt> represents boolean expression <tt class="docutils literal"><span class="pre">x</span> <span class="pre">or</span> <span class="pre">y</span> <span class="pre">or</span> <span class="pre">..</span></tt>.
Operand algebra class is <tt class="docutils literal"><span class="pre">Logic</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">Lt(x,</span> <span class="pre">y)</span></tt> represents relational expression <tt class="docutils literal"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</span></tt>.
Operand algebra class is <tt class="docutils literal"><span class="pre">Calculus</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">Le(x,</span> <span class="pre">y)</span></tt> represents relational expression <tt class="docutils literal"><span class="pre">x</span> <span class="pre">&lt;=</span> <span class="pre">y</span></tt>.
Operand algebra class is <tt class="docutils literal"><span class="pre">Calculus</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">Gt(x,</span> <span class="pre">y)</span></tt> represents relational expression <tt class="docutils literal"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">y</span></tt>.
Operand algebra class is <tt class="docutils literal"><span class="pre">Calculus</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">Ge(x,</span> <span class="pre">y)</span></tt> represents relational expression <tt class="docutils literal"><span class="pre">x</span> <span class="pre">&gt;=</span> <span class="pre">y</span></tt>.
Operand algebra class is <tt class="docutils literal"><span class="pre">Calculus</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">Eq(x,</span> <span class="pre">y)</span></tt> represents relational expression <tt class="docutils literal"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</span></tt>.
Operand algebra class is <tt class="docutils literal"><span class="pre">Calculus</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">Ne(x,</span> <span class="pre">y)</span></tt> represents relational expression <tt class="docutils literal"><span class="pre">x</span> <span class="pre">!=</span> <span class="pre">y</span></tt>.
Operand algebra class is <tt class="docutils literal"><span class="pre">Calculus</span></tt>.</li>
</ol>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id13" id="collecting-field" name="collecting-field">3.7&nbsp;&nbsp;&nbsp;Collecting field</a></h2>
<p>SympyCore defines <tt class="docutils literal"><span class="pre">CollectingField</span></tt> class to represent sums and
products in <tt class="docutils literal"><span class="pre">{&lt;term&gt;:&lt;coefficent&gt;}</span></tt> and <tt class="docutils literal"><span class="pre">{&lt;base&gt;:&lt;exponent&gt;}</span></tt>
forms, respectively. The class name contains prefix &quot;Collecting&quot;
because in operations with <tt class="docutils literal"><span class="pre">CollectingField</span></tt> instances, equal terms
and equal bases are automatically collected by upgrading the
coefficient and exponent values, respectively.</p>
<p>The following operations are defined by the <tt class="docutils literal"><span class="pre">CollectingField</span></tt> and
its subclasses <tt class="docutils literal"><span class="pre">Calculus</span></tt>, <tt class="docutils literal"><span class="pre">Unit</span></tt>:</p>
<ol class="arabic simple">
<li><tt class="docutils literal"><span class="pre">Add(x,</span> <span class="pre">y,</span> <span class="pre">..)</span></tt> represents addition <tt class="docutils literal"><span class="pre">x</span> <span class="pre">+</span> <span class="pre">y</span> <span class="pre">+</span> <span class="pre">..</span></tt>.
Operand algebra class is the same as algebra class.</li>
<li><tt class="docutils literal"><span class="pre">Mul(x,</span> <span class="pre">y,</span> <span class="pre">..)</span></tt> represents multiplication <tt class="docutils literal"><span class="pre">x</span> <span class="pre">*</span> <span class="pre">y</span> <span class="pre">*</span> <span class="pre">..</span></tt>.
Operand algebra class is the same as algebra class.</li>
<li><tt class="docutils literal"><span class="pre">Terms((x,a),</span> <span class="pre">(y,b),</span> <span class="pre">..)</span></tt> represents a sum <tt class="docutils literal"><span class="pre">a*x</span> <span class="pre">+</span> <span class="pre">b*y</span> <span class="pre">+</span> <span class="pre">..</span></tt>
where <tt class="docutils literal"><span class="pre">x,</span> <span class="pre">y,</span> <span class="pre">..</span></tt> must be non-numeric instances of the algebra
class and <tt class="docutils literal"><span class="pre">a,</span> <span class="pre">b,</span> <span class="pre">..</span></tt> are low-level numbers.</li>
<li><tt class="docutils literal"><span class="pre">Factors((x,a),</span> <span class="pre">(y,b),</span> <span class="pre">..)</span></tt> represents a product <tt class="docutils literal"><span class="pre">x**a</span> <span class="pre">*</span> <span class="pre">y**b</span> <span class="pre">*</span> <span class="pre">..</span></tt>
where <tt class="docutils literal"><span class="pre">x,</span> <span class="pre">y,</span> <span class="pre">..</span></tt> must be instances of the algebra
class and <tt class="docutils literal"><span class="pre">a,</span> <span class="pre">b,</span> <span class="pre">..</span></tt> are either low-level numbers or instances of
exponent algebra.</li>
<li><tt class="docutils literal"><span class="pre">Pow(x,</span> <span class="pre">y)</span></tt> represents exponentiation <tt class="docutils literal"><span class="pre">x</span> <span class="pre">**</span> <span class="pre">y</span></tt> where <tt class="docutils literal"><span class="pre">x</span></tt> must
be instance of the algebra class and <tt class="docutils literal"><span class="pre">y</span></tt> must be either low-level
number or an instance of exponent algebra.</li>
<li><tt class="docutils literal"><span class="pre">Sub(x,</span> <span class="pre">y,</span> <span class="pre">..)</span></tt> represents operation <tt class="docutils literal"><span class="pre">x</span> <span class="pre">-</span> <span class="pre">y</span> <span class="pre">-</span> <span class="pre">..</span></tt> where operands
must be instances of the algebra class.</li>
<li><tt class="docutils literal"><span class="pre">Div(x,</span> <span class="pre">y,</span> <span class="pre">..)</span></tt> represents operation <tt class="docutils literal"><span class="pre">x</span> <span class="pre">/</span> <span class="pre">y</span> <span class="pre">/</span> <span class="pre">..</span></tt> where operands
must be instances of the algebra class.</li>
<li><tt class="docutils literal"><span class="pre">Apply(f,</span> <span class="pre">(x,</span> <span class="pre">y,</span> <span class="pre">..))</span></tt> represents unevaluated function call
<tt class="docutils literal"><span class="pre">f(x,</span> <span class="pre">y,</span> <span class="pre">..)</span></tt>.</li>
</ol>
</div>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id14" id="defining-functions-in-sympycore" name="defining-functions-in-sympycore">4&nbsp;&nbsp;&nbsp;Defining functions in SympyCore</a></h1>
<p>In general, unevaluated applied functions in <tt class="docutils literal"><span class="pre">sympycore</span></tt> are
represented as a pair:</p>
<pre class="literal-block">
&lt;Algebra class&gt;(&lt;callable&gt;, &lt;arguments&gt;)
</pre>
<p>where <tt class="docutils literal"><span class="pre">&lt;Algebra</span> <span class="pre">class&gt;</span></tt> defines an algebra where the function values
belong to, <tt class="docutils literal"><span class="pre">&lt;callable&gt;</span></tt> is a Python callable object that may define
some basic canonization rules, and <tt class="docutils literal"><span class="pre">&lt;arguments&gt;</span></tt> is either a tuple
of function arguments or for single argument functions, the argument
itself.</p>
<p>To simplify the infrastructure for handling defined functions, the
defined functions in <tt class="docutils literal"><span class="pre">sympycore</span></tt> should be defined as classes
derived from <tt class="docutils literal"><span class="pre">DefinedFunction</span></tt> class (defined in
<tt class="docutils literal"><span class="pre">sympycore.core</span></tt>). Such defined functions will be available as
attributes of the <tt class="docutils literal"><span class="pre">defined_functions</span></tt> holder object, and most
importantly, the expression string parser will recognize symbols with
defined function names as defined functions.</p>
<p>Here follows a typical definition of a defined function <tt class="docutils literal"><span class="pre">myfunc</span></tt> for
a given <tt class="docutils literal"><span class="pre">Algebra</span></tt> class:</p>
<pre class="literal-block">
class myfunc(DefinedFunction):

    def __new__(cls, *args):
        # perform any canonization of arguments (including
        # converting arguments to operands algebra) and return
        # simplified result. Otherwise,
        return Algebra(cls, args)
</pre>
</div>
<div class="section">
<h1><a class="toc-backref" href="#id15" id="how-does-it-work-in-sympycore" name="how-does-it-work-in-sympycore">5&nbsp;&nbsp;&nbsp;How does it work in SympyCore?</a></h1>
<div class="section">
<h2><a class="toc-backref" href="#id16" id="how-strings-are-parsed-to-expressions" name="how-strings-are-parsed-to-expressions">5.1&nbsp;&nbsp;&nbsp;How strings are parsed to expressions?</a></h2>
<p>Expressions represent elements of some algebra.  Therefore, to parse a
string and to create an expression from it, one needs to specify to
which algebra the expression should belong to. In sympycore, this is
done by calling the corresponding algebra constructor with a single
string argument:</p>
<pre class="literal-block">
Algebra('&lt;expr&gt;')
</pre>
<p>that will return the result of <tt class="docutils literal"><span class="pre">Algebra.convert('&lt;expr&gt;')</span></tt>. Continue
reading the next section about the <tt class="docutils literal"><span class="pre">convert</span></tt> method.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id17" id="how-arbitrary-python-objects-are-converted-to-expressions" name="how-arbitrary-python-objects-are-converted-to-expressions">5.2&nbsp;&nbsp;&nbsp;How arbitrary Python objects are converted to expressions?</a></h2>
<p>Each algebra class has classmethod <tt class="docutils literal"><span class="pre">convert(&lt;obj&gt;,</span> <span class="pre">typeerror=True)</span></tt>
that is used to convert arbitrary Python objects to Algebra instances.
The following algorithm is used:</p>
<ol class="arabic simple">
<li>If <tt class="docutils literal"><span class="pre">&lt;obj&gt;</span></tt> is already <tt class="docutils literal"><span class="pre">Algebra</span></tt> instance, then it is returned
immidiately.</li>
<li>Next, the classmethod <tt class="docutils literal"><span class="pre">Algebra.convert_number(&lt;obj&gt;,</span> <span class="pre">typeerror)</span> <span class="pre">-&gt;</span>
<span class="pre">r</span></tt> is called. On success, <tt class="docutils literal"><span class="pre">Algebra.Number(r)</span></tt> is returned. In
most cases, <tt class="docutils literal"><span class="pre">Algebra.Number</span></tt> class method just returns
<tt class="docutils literal"><span class="pre">cls(NUMBER,</span> <span class="pre">r)</span></tt>. But there exist exceptions.</li>
<li>Next, if <tt class="docutils literal"><span class="pre">&lt;obj&gt;</span></tt> is Python string or <tt class="docutils literal"><span class="pre">Verbatim</span></tt> instance, then
<tt class="docutils literal"><span class="pre">Verbatim.convert(&lt;obj&gt;).as_algebra(Algebra)</span></tt> is returned.</li>
<li>Next, if <tt class="docutils literal"><span class="pre">&lt;obj&gt;</span></tt> is some algebra instance then
<tt class="docutils literal"><span class="pre">&lt;obj&gt;.as_algebra(Algebra)</span></tt> is returned.</li>
<li>Finally, if none of the above did not return a result, then
<tt class="docutils literal"><span class="pre">TypeError</span></tt> will be raised when <tt class="docutils literal"><span class="pre">typeerror</span></tt> is
<tt class="docutils literal"><span class="pre">True</span></tt>. Otherwise <tt class="docutils literal"><span class="pre">NotImplemented</span></tt> will be returned.</li>
</ol>
<p>Continue reading the next section about the <tt class="docutils literal"><span class="pre">as_algebra</span></tt> method.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id18" id="how-algebra-expressions-are-converted-to-other-algebras" name="how-algebra-expressions-are-converted-to-other-algebras">5.3&nbsp;&nbsp;&nbsp;How algebra expressions are converted to other algebras?</a></h2>
<p>Each algebra class has instance method <tt class="docutils literal"><span class="pre">as_algebra(&lt;other</span> <span class="pre">algebra</span>
<span class="pre">class&gt;)</span></tt> that is used to convert instances of one algebra class to
instances of another algebra class. By default, the conversion is
carried out using the intermediate <tt class="docutils literal"><span class="pre">Verbatim</span></tt> algebra. First, the
instance of one algebra is converted to <tt class="docutils literal"><span class="pre">Verbatim</span></tt> algebra and then
the instance of a <tt class="docutils literal"><span class="pre">Verbatim</span></tt> algebra is converted to another
algebra. So, every algebra class must define <tt class="docutils literal"><span class="pre">as_verbatim()</span></tt>
instance method that should return a <tt class="docutils literal"><span class="pre">Verbatim</span></tt> instance containing
verbatim representation of the algebra expression.</p>
<p>Of course, if an expression in one algebra does not make sense as an
expression of the other algebra, the <tt class="docutils literal"><span class="pre">TypeError</span></tt> will be raised.</p>
<p>Continue reading the next section about the <tt class="docutils literal"><span class="pre">Verbatim.as_algebra</span></tt>
method.</p>
</div>
<div class="section">
<h2><a class="toc-backref" href="#id19" id="how-verbatim-expressions-are-converted-to-other-algebras" name="how-verbatim-expressions-are-converted-to-other-algebras">5.4&nbsp;&nbsp;&nbsp;How verbatim expressions are converted to other algebras?</a></h2>
<p>Verbatim expressions are converted to another algebras in <tt class="docutils literal"><span class="pre">&lt;Verbatim</span>
<span class="pre">instance&gt;.as_algebra(&lt;Algebra</span> <span class="pre">class&gt;)</span></tt> instance method. <tt class="docutils literal"><span class="pre">Verbatim</span></tt>
instance holds a pair <tt class="docutils literal"><span class="pre">(&lt;expression</span> <span class="pre">head&gt;,</span> <span class="pre">&lt;expression</span> <span class="pre">data&gt;)</span></tt> and
the task of <tt class="docutils literal"><span class="pre">as_algebra</span></tt> method is to use information in triple
<tt class="docutils literal"><span class="pre">&lt;expression</span> <span class="pre">head&gt;,</span> <span class="pre">&lt;expression</span> <span class="pre">data&gt;,</span> <span class="pre">&lt;Algebra</span> <span class="pre">class&gt;</span></tt> and
construct an <tt class="docutils literal"><span class="pre">&lt;Algebra&gt;</span></tt> instance representing expression in the
given algebra.</p>
<p>First, let us consider atomic expressions such as numbers and symbols.</p>
<p>In general, numbers can be low-level numbers such as <tt class="docutils literal"><span class="pre">int</span></tt>,
<tt class="docutils literal"><span class="pre">long</span></tt>, <tt class="docutils literal"><span class="pre">mpq</span></tt>, <tt class="docutils literal"><span class="pre">mpf</span></tt>, <tt class="docutils literal"><span class="pre">mpc</span></tt>, <tt class="docutils literal"><span class="pre">mpqc</span></tt>, but numbers of one
algebra can be expressions of some other algebra. So, in case of
verbatim numbers, <tt class="docutils literal"><span class="pre">Algebra.convert(&lt;Verbatim</span> <span class="pre">instance&gt;.data)</span></tt> is
returned.</p>
<p>In general, symbols are Python string objects but certain string
values may be names of mathematical constants or predefined functions
for the given algebra. So, in the case of verbatim symbols,
<tt class="docutils literal"><span class="pre">Algebra.convert_symbol(&lt;Verbatim</span> <span class="pre">instance&gt;.data)</span></tt> is returned.  It
also means that <tt class="docutils literal"><span class="pre">Algebra</span></tt> classes must define classmethod
<tt class="docutils literal"><span class="pre">convert_symbol</span></tt> that can either return a algebra symbol instance
<tt class="docutils literal"><span class="pre">Algebra(SYMBOL,</span> <span class="pre">data)</span></tt> or a predefined function or mathematical
constant.</p>
<p>Expressions are operations with operands. Therefore, to convert
verbatim expression to an expression of a given algebra, the algebra
must have a support for the given operation. The following table
summarizes how algebras can support different operations.</p>
<table border="1" class="docutils">
<colgroup>
<col width="26%" />
<col width="74%" />
</colgroup>
<tbody valign="top">
<tr><td>Expression head</td>
<td>Support hooks in <tt class="docutils literal"><span class="pre">Algebra</span></tt> class</td>
</tr>
<tr><td>POS</td>
<td><tt class="docutils literal"><span class="pre">Algebra.__pos__(operand)</span></tt></td>
</tr>
<tr><td>NEG</td>
<td><tt class="docutils literal"><span class="pre">Algebra.__neg__(operand)</span></tt></td>
</tr>
<tr><td>ADD</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Add(*operands)</span></tt></td>
</tr>
<tr><td>SUB</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Sub(*operands)</span></tt></td>
</tr>
<tr><td>MUL</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Mul(*operands)</span></tt></td>
</tr>
<tr><td>DIV</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Div(*operands)</span></tt></td>
</tr>
<tr><td>POW</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Pow(*operands)</span></tt></td>
</tr>
<tr><td>MOD</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Mod(*operands)</span></tt></td>
</tr>
<tr><td>LT</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Lt(*operands)</span></tt></td>
</tr>
<tr><td>GT</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Gt(*operands)</span></tt></td>
</tr>
<tr><td>LE</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Le(*operands)</span></tt></td>
</tr>
<tr><td>GE</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Ge(*operands)</span></tt></td>
</tr>
<tr><td>EQ</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Eq(*operands)</span></tt></td>
</tr>
<tr><td>NE</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Ne(*operands)</span></tt></td>
</tr>
<tr><td>AND</td>
<td><tt class="docutils literal"><span class="pre">Algebra.And(*operands)</span></tt></td>
</tr>
<tr><td>OR</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Or(*operands)</span></tt></td>
</tr>
<tr><td>NOT</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Not(*operands)</span></tt></td>
</tr>
<tr><td>IN</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Element(*operands)</span></tt></td>
</tr>
<tr><td>NOTIN</td>
<td><tt class="docutils literal"><span class="pre">Algebra.Not(Algebra.Element(*operands))</span></tt></td>
</tr>
<tr><td>APPLY</td>
<td>XXX</td>
</tr>
</tbody>
</table>
<p>Note that the operands to operations of a given algebra do not always
belong to the same algebra. For example, the operands of <tt class="docutils literal"><span class="pre">LT</span></tt> can be
<tt class="docutils literal"><span class="pre">Calculus</span></tt> instances but the operation result is <tt class="docutils literal"><span class="pre">Logic</span></tt> instance.
The algebras can also vary within a list of operands. For example, the
first operand to <tt class="docutils literal"><span class="pre">IN</span></tt> should be an instance of set element algebra
while the second operand is a <tt class="docutils literal"><span class="pre">Set</span></tt> instance.
To support all these cases, the algebra class may need to define the
following additional methods:</p>
<ol class="arabic simple">
<li><tt class="docutils literal"><span class="pre">Algebra.get_operand_algebra(head,</span> <span class="pre">index=0)</span></tt> - return the algebra
class of <tt class="docutils literal"><span class="pre">index</span></tt>-th operand in operation defined by <tt class="docutils literal"><span class="pre">head</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">&lt;Algebra</span> <span class="pre">instance&gt;.get_element_algebra()</span></tt> - return the element
algebra class. The method must be defined by <tt class="docutils literal"><span class="pre">Set</span></tt> and
<tt class="docutils literal"><span class="pre">MatrixRing</span></tt> classes, for instance. This method is instance
method because the result may depend the instance content. For
example, <tt class="docutils literal"><span class="pre">Set('Reals').get_element_algebra()</span></tt> would return
<tt class="docutils literal"><span class="pre">Calculus</span></tt> while <tt class="docutils literal"><span class="pre">Set('Functions').get_element_algebra()</span></tt>
should return <tt class="docutils literal"><span class="pre">FunctionRing</span></tt>.</li>
</ol>
</div>
</div>
</div>
</body>
</html>
